package com.xmm.view;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JTree;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import com.xmm.constants.CONSTANTS;
import com.xmm.listener.MenuActionListener;
import com.xmm.listener.MouseActionListener;
import com.xmm.model.Ablum;
import com.xmm.model.Library;
import com.xmm.model.Music;
import com.xmm.model.Track;

public class MusicTree extends JTree implements MenuActionListener{
	private final static String ROOT = "Root";
	/**
	 * 
	 */
	private static final long serialVersionUID = 3795131176631137272L;

	private static MusicTreeNode mRoot = new MusicTreeNode(ROOT);
	
	private MouseActionListener mClickListener = null;
	
	public MusicTree() {
		super(mRoot);
		
		init();
	}
	
	public void setClickListener(MouseActionListener clickListener) {
		mClickListener = clickListener;
	}

	private void init() {
		this.addMouseListener(ml);
	}
	
	private MouseListener ml = new MouseAdapter() {
		public void mousePressed(MouseEvent e) {
	         int selRow = MusicTree.this.getRowForLocation(e.getX(), e.getY());
	         TreePath selPath = MusicTree.this.getPathForLocation(e.getX(), e.getY());
	         MusicTree.this.setSelectionPath(selPath);
	         
	         if(selRow != -1) {
				if (e.getButton() == MouseEvent.BUTTON1) {
					// left button
					if (e.getClickCount() == 1) {
						SingleClick(selRow, selPath);
					} else if (e.getClickCount() == 2) {
						DoubleClick(selRow, selPath);
					}
				} else if (e.getButton() == MouseEvent.BUTTON3) {
					// right button
					RightClick(e, selRow, selPath);
				}
	         }
	     }
	};
	
	private void SingleClick(int selRow, TreePath selPath) {
		if(selPath == null) return;
		
		DefaultMutableTreeNode node = (DefaultMutableTreeNode)getLastSelectedPathComponent();
		if (node instanceof MusicTreeNode) {
			if(((MusicTreeNode)node).isTrack()) {
				if(mClickListener != null) {
					mClickListener.doSingleClick(((Track)(((MusicTreeNode)node).getMusic())).getAllProps());
				}
			} else if(((MusicTreeNode)node).isAblum()) {
				if(mClickListener != null) {
					mClickListener.doSingleClick(((Ablum)(((MusicTreeNode)node).getMusic())).getAllProps());
				}
			}
		}
	}
	
	private void DoubleClick(int selRow, TreePath selPath) {
		if(mClickListener != null) {
			mClickListener.doDoubleClick(null);
		}
	}
	
	private void RightClick(MouseEvent e, int selRow, TreePath selPath) {
		if(selPath == null) return;
		
		DefaultMutableTreeNode node = (DefaultMutableTreeNode)getLastSelectedPathComponent();
		if (node instanceof MusicTreeNode) {
			MusicTreeNodeMenu menu = null;
			menu = new MusicTreeNodeMenu(((MusicTreeNode)node));
			menu.setMenuActionListener(this);
			menu.show(e.getComponent(), e.getX(), e.getY());
			
			if (mClickListener != null) {
				mClickListener.doRightClick(null);
			}
		}
	}

	@Override
	public void doAddLib(MusicTreeNode parent) {
		String name = JOptionPane.showInputDialog(null, "Please Enter Library Name", 
				"Create Library", JOptionPane.DEFAULT_OPTION);
		if(name == null || "".equals(name)) return;
		MusicTreeNode son = new MusicTreeNode(CONSTANTS.NODE_TYPE_LIBRARY, name);
		Library library = new Library(name);
		son.setMusic(library);
		parent.add(son);
		((DefaultTreeModel)getModel()).reload(parent);
	}

	@Override
	public void doDelLib(MusicTreeNode me) {
		int select = JOptionPane.showConfirmDialog(null, "are you sure delete library", 
				"Make Sure", JOptionPane.YES_NO_OPTION);
		switch(select) {
		case JOptionPane.YES_OPTION:
			TreeNode node = me.getParent();
			me.removeFromParent();
			((DefaultTreeModel)getModel()).reload(node);
			break;
		case JOptionPane.NO_OPTION:
			break;
		}
	}

	@Override
	public void doAddAblum(MusicTreeNode parent) {
		String name = JOptionPane.showInputDialog(null, "Please Enter Ablum Name", 
				"Create Ablum", JOptionPane.DEFAULT_OPTION);
		if(name == null || "".equals(name)) return;
		MusicTreeNode son = new MusicTreeNode(CONSTANTS.NODE_TYPE_ABLUM, name);
		Ablum ablum = new Ablum(name);
		Music music = parent.getMusic();
		((Library)music).addMusic(ablum);
		
		son.setMusic(ablum);
		parent.add(son);
		((DefaultTreeModel)getModel()).reload(parent);
	}

	@Override
	public void doDelAblum(MusicTreeNode me) {
		int select = JOptionPane.showConfirmDialog(null, "are you sure delete ablum", 
				"Make Sure", JOptionPane.YES_NO_OPTION);
		switch(select) {
		case JOptionPane.YES_OPTION:
			TreeNode parent = me.getParent();
			me.removeFromParent();
			((MusicTreeNode)me).removeFromNode(me.getCodeId());
			((DefaultTreeModel)getModel()).reload(parent);
			break;
		case JOptionPane.NO_OPTION:
			break;
		}
	}

	@Override
	public void doAddTrack(MusicTreeNode parent) {
		JFileChooser chooser = new JFileChooser("Add Mp3");
		chooser.setFileSelectionMode(JFileChooser.OPEN_DIALOG);
		FileFilter ff = new FileNameExtensionFilter("Media(*.mp3)", new String[]{"mp3"});
		chooser.setFileFilter(ff);
		if(chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
			MusicTreeNode son = new MusicTreeNode(CONSTANTS.NODE_TYPE_TRACK, 
					chooser.getSelectedFile().getName());
			
			Track track = new Track(chooser.getSelectedFile());
			son.setMusic(track);
			Music music = parent.getMusic();
			if(music instanceof Library) {
				((Library)music).addMusic(track);
			} else if(music instanceof Ablum) {
				((Ablum)music).AddTrack(track);
			}
			
			son.setMusic(track);
			parent.add(son);
			((DefaultTreeModel)getModel()).reload(parent);
		}
	}

	@Override
	public void doAddTrackByPeople(MusicTreeNode parent) {
		TrackInputDialog dialog = new TrackInputDialog();
		dialog.show(this);
		
		String title = dialog.getTitle();
		if(title == null || "".equals(title)) {
			return;
		}
		MusicTreeNode son = new MusicTreeNode(CONSTANTS.NODE_TYPE_TRACK, title);
		
		Track track = new Track(dialog.getAllProps());
		son.setMusic(track);
		Music music = parent.getMusic();
		if(music instanceof Library) {
			((Library)music).addMusic(track);
		} else if(music instanceof Ablum) {
			((Ablum)music).AddTrack(track);
		}
		
		son.setMusic(track);
		parent.add(son);
		((DefaultTreeModel)getModel()).reload(parent);
	}
	
	@Override
	public void doDelTrack(MusicTreeNode me) {
		int select = JOptionPane.showConfirmDialog(null, "are you sure delete Track", 
				"Make Sure", JOptionPane.YES_NO_OPTION);
		switch(select) {
		case JOptionPane.YES_OPTION:
			TreeNode node = me.getParent();
			me.removeFromParent();
			((MusicTreeNode)node).removeFromNode(me.getCodeId());
			((DefaultTreeModel)getModel()).reload(node);
			break;
		case JOptionPane.NO_OPTION:
			break;
		}
	}
}